/**
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain an copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.carl.cutimgutil.util;

import com.carl.cutimgutil.NineCropType;
import com.carl.cutimgutil.model.LocalImage;
import ohos.agp.components.Image;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * ImageCutUtils
 *
 * @author AnBetter
 * @since 2021-05-11
 */
public class ImageCutUtils {
    private ImageCutUtils() {

    }

    /** cutNinePic
     *
     * @param imdel
     * @param image
     * @param context
     * @return PixelMap
     * @throws IOException
     * @throws NotExistException
     */
    public static PixelMap cutNinePic(LocalImage imdel, Image image, Context context)
            throws IOException, NotExistException {
        final int three = 3;
        final int two = 2;
        final int mscreenHeight = 150;
        PixelMap pixelMap;
        pixelMap = idToPixelMap(imdel.getDrawableResource(), context);
        int widthX = pixelMap.getImageInfo().size.width / three;
        int heightY = pixelMap.getImageInfo().size.height / three;
        DisplayAttributes attributes = DisplayManager.getInstance().
                getDefaultDisplay(context).get().getRealAttributes();
        int screenWidth = attributes.width;
        int screenHeight = attributes.height;
        if (imdel.getCropType() == NineCropType.NONE) {
            if (widthX > heightY) { // 横向图片
                image.setWidth(screenWidth);
                image.setHeight(Math.round((float) screenWidth * heightY / widthX));
            } else { // 纵向图片
                image.setWidth(Math.round((float) (screenHeight - mscreenHeight) * widthX / heightY));
                image.setHeight(screenHeight - mscreenHeight);
            }
            PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
            options.size = new Size(image.getWidth(), image.getHeight());
            return PixelMap.create(pixelMap, options);
        }
        if (widthX > heightY) { // 横向图片
            image.setWidth(screenWidth);
            image.setHeight(Math.round((float) screenWidth * heightY / widthX));
        } else { // 纵向图片
            image.setWidth(Math.round((float) (screenHeight - mscreenHeight) * widthX / heightY));
            image.setHeight(screenHeight - mscreenHeight);
        }
        List<Rect> corpModelList = new ArrayList<>();
        corpModelList.add(new Rect(0, 0, widthX, heightY));
        corpModelList.add(new Rect(widthX, 0, widthX, heightY));
        corpModelList.add(new Rect(two * widthX, 0, widthX, heightY));
        corpModelList.add(new Rect(0, heightY, widthX, heightY));
        corpModelList.add(new Rect(widthX, heightY, widthX, heightY));
        corpModelList.add(new Rect(two * widthX, heightY, widthX, heightY));
        corpModelList.add(new Rect(0, two * heightY, widthX, heightY));
        corpModelList.add(new Rect(widthX, two * heightY, widthX, heightY));
        corpModelList.add(new Rect(two * widthX, two * heightY, widthX, heightY));
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.size = new Size(image.getWidth(), image.getHeight());
        PixelMap cutPixel;
        cutPixel = PixelMap.create(pixelMap, corpModelList.get(imdel.getCropType()), options);
        return cutPixel;
    }

    /** cutvThreePic
     *
     * @param imdel
     * @param image
     * @param context
     * @return PixelMap
     * @throws IOException
     * @throws NotExistException
     */
    public static PixelMap cutvThreePic(LocalImage imdel, Image image, Context context)
            throws IOException, NotExistException {
        PixelMap pixelMap;
        final int three = 3;
        final int two = 2;
        final int twenty = 20;
        final int mscreenHeight = 150;
        pixelMap = idToPixelMap(imdel.getDrawableResource(), context);
        if (imdel.getCropType() == NineCropType.NONE) {
            return pixelMap;
        }
        int widthX = pixelMap.getImageInfo().size.width;
        int heightY = pixelMap.getImageInfo().size.height / three;
        DisplayAttributes attributes = DisplayManager.getInstance().getDefaultDisplay(context)
                .get().getRealAttributes();
        int screenWidth = attributes.width;
        int screenHeight = attributes.height;
        if (widthX > heightY) { // 横向图片
            image.setWidth(screenWidth - twenty);
            image.setHeight(Math.round((float)screenWidth * heightY / widthX));
        } else { // 纵向图片
            image.setWidth(Math.round((float) (screenHeight - mscreenHeight) * widthX / heightY) - twenty);
            image.setHeight(screenHeight - mscreenHeight);
        }
        List<Rect> corpModelList = new ArrayList<>();
        corpModelList.add(new Rect(0, 0, widthX, heightY));
        corpModelList.add(new Rect(0, heightY, widthX, heightY));
        corpModelList.add(new Rect(0, two * heightY, widthX, heightY));
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.size = new Size(image.getWidth(), image.getHeight());
        PixelMap cutPixel;
        cutPixel = PixelMap.create(pixelMap, corpModelList.get(imdel.getCropType()), options);
        return cutPixel;
    }

    /** cuthThreePic
     *
     * @param imdel
     * @param image
     * @param context
     * @return PixelMap
     * @throws IOException
     * @throws NotExistException
     */
    public static PixelMap cuthThreePic(LocalImage imdel, Image image, Context context)
            throws IOException, NotExistException {
        PixelMap pixelMap;
        PixelMap cutPixel;
        final int three = 3;
        final int two = 2;
        final int twenty = 20;
        final int mscreenHeight = 150;
        pixelMap = idToPixelMap(imdel.getDrawableResource(), context);
        if (imdel.getCropType() == NineCropType.NONE) {
            return pixelMap;
        }
        int widthX = pixelMap.getImageInfo().size.width / three;
        int heightY = pixelMap.getImageInfo().size.height;

        DisplayAttributes attributes = DisplayManager.getInstance()
                .getDefaultDisplay(context).get().getRealAttributes();
        int screenWidth = attributes.width;
        int screenHeight = attributes.height;
        if (widthX > heightY) {
            image.setWidth(two * widthX);
            image.setHeight(two * heightY);
        }

        List<Rect> corpModelList = new ArrayList<>();
        corpModelList.add(new Rect(0, 0, widthX, heightY));
        corpModelList.add(new Rect(widthX, 0, widthX, heightY));
        corpModelList.add(new Rect(two * widthX, 0, widthX, heightY));

        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();

        options.size = new Size(image.getWidth(), image.getHeight());
        cutPixel = PixelMap.create(pixelMap, corpModelList.get(imdel.getCropType()), options);
        return cutPixel;
    }

    private static PixelMap idToPixelMap(int resId, Context context) throws IOException, NotExistException {
        InputStream drawableInputStream = context.getResourceManager().getResource(resId);
        ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
        sourceOptions.formatHint = "image/png";
        ImageSource imageSource = ImageSource.create(drawableInputStream, null);
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.desiredSize = new Size(0, 0);
        decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
        decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
        PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
        return pixelMap;
    }
}
